package com.linsir.lin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDto;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.linsir.base.SearchPara;
import com.linsir.core.BaseResponse;
import com.linsir.core.CodeEnum;
import com.linsir.lin.dto.AccountDTO;
import com.linsir.lin.dto.GridDTO;
import com.linsir.lin.mapper.AccountMapper;
import com.linsir.lin.pojo.*;
import com.linsir.lin.service.*;
import com.linsir.utils.StringUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service(value = "accountService")
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements IService<Account>, AccountService {

    @Autowired
    private AccountRoleService accountRoleService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private BaseCodeService baseCodeService;

    @Autowired
    private RolePermissonService rolePermissonService;

    @Autowired
    private PermissionService permissionService;

    /**
     * 增加账号
     *
     * @param account
     * @return
     */
    @Override
    public BaseResponse<Boolean> addOrUpdate(Account account) throws ParseException {

        String password = account.getPassword();  //明文密码

        ByteSource salt = ByteSource.Util.bytes(account.getUserName()); //盐值

        int hashIterations=1024;

        SimpleHash simpleHash = new SimpleHash("MD5",password,salt,hashIterations);

        account.setPassword(simpleHash.toString());

        account.setPasswordSalt(salt.toString());

        account.setDisabled(true);

        account.setExpires(new Date(new SimpleDateFormat("yyyy-MM-dd").parse("2099-12-31").getTime()));

        boolean data = saveOrUpdate(account);
        if (data)
        {
            return new BaseResponse<Boolean>(CodeEnum.SUCCESS,"账户增加成果",data);
        }
        else
        {
            return new BaseResponse<Boolean>(CodeEnum.FAILED,"账户增加失败",data);
        }
    }

    /**
     * 列表
     *
     * @param page
     * @param limit
     * @param searchParams
     * @return
     */
    @Override
    public GridDTO<AccountDTO> grid(String page, String limit, String searchParams) throws IOException, InvocationTargetException, IllegalAccessException {

        Map<String,String> map = SearchPara.toMap(searchParams);

        QueryWrapper<Account> wrapper=new QueryWrapper<Account>();

        wrapper.orderByDesc("id");

        if (map!=null)
        {
            wrapper.like("user_name",map.get("userName"));
        }

        Page<Account> pageDto = new PageDto<Account>();
        pageDto.setCurrent(Long.parseLong(page));
        pageDto.setSize(Long.parseLong(limit));
        pageDto = super.baseMapper.selectPage(pageDto,wrapper);
        List<AccountDTO> accountDTOList = toDtoList(pageDto.getRecords());
        return new GridDTO<AccountDTO>("0","成功",pageDto.getSize(),accountDTOList);
    }

    /**
     * 根据账号找到角色列表
     *
     * @param account
     * @return
     */
    @Override
    public List<Role> rolesByAccount(Account account) {
        List<AccountRole> accountRoleList = accountRoleService.accountRoleList(account.getId());
        List<Role> roles = new ArrayList<Role>();
        if (accountRoleList.size()>0)
        {
            roles=roleService.roles(accountRoleList);
        }
        return roles;
    }

    /**
     * 根据账号，获取角色名称列表
     *
     * @param account
     * @return
     */
    @Override
    public Set<String> roleStrs(Account account) {
        List<Role> roleList = rolesByAccount(account);

        Set<String> roleStrs =new HashSet<String>();
        if (roleList.size()>0)
        {
            for (Role role : roleList)
            {
                roleStrs.add(role.getName());
            }
        }
        return roleStrs;
    }


    /**
     * 角色变成，角色字符串
     *
     * @param roleList
     * @return
     */
    @Override
    public String rolestoRoleStr(List<Role> roleList) {
        List<String> Strs = new ArrayList<String>();
        String roleSStr;
        if (roleList.size()>0)
        {
            for (Role role : roleList)
            {
                Strs.add(role.getName());
            }
            roleSStr=String.join(",",Strs);
        }
        else {
            roleSStr=null;
        }
        return roleSStr;

    }


    /**
     * 账号转化DTO
     *
     * @param account
     * @return
     */
    @Override
    public AccountDTO toDto(Account account) throws InvocationTargetException, IllegalAccessException {
        AccountDTO accountDTO =new AccountDTO();
        BeanUtils.copyProperties(accountDTO,account);
        List<Role> roleList = rolesByAccount(account);
        String roleSStr=rolestoRoleStr(roleList);
        String disabledName = baseCodeService.codeName("disabled",String.valueOf(account.isDisabled()));
        accountDTO.setDisabledName(disabledName);
        accountDTO.setRoleList(roleList);
        accountDTO.setRoleStr(roleSStr);
        return accountDTO;
    }

    /**
     * 账号转化DTOList
     *
     * @param accounts
     */
    @Override
    public List<AccountDTO> toDtoList(List<Account> accounts) throws InvocationTargetException, IllegalAccessException {
        List<AccountDTO> accountDTOList = new ArrayList<AccountDTO>();
        for (Account account : accounts)
        {
            AccountDTO accountDTO =new AccountDTO();
            accountDTO =toDto(account);
            accountDTOList.add(accountDTO);
        }
        return accountDTOList;
    }

    /**
     * 根据账号找到所有的权限
     *
     * @param account
     * @return
     */
    @Override
    public List<Permission> getPerminssionByAccount(Account account) {
        List<Role> roleList = rolesByAccount(account);

        List<Permission> permissionList = new  ArrayList<Permission> ();

        if (roleList.size()>0)
        {
            for (Role role : roleList)
            {
                List<RolePermisson> rolePermissonList = rolePermissonService.rolePermissons(role);
                if (rolePermissonList.size()>0)
                {
                   for (RolePermisson rolePermisson : rolePermissonList)
                   {
                       permissionList.add(permissionService.permissionByRolePermission(rolePermisson));
                   }
                }
            }
        }

        return permissionList;
    }

    @Override
    public Set<String> perminssionStrs(List<Permission> permissionList) {
        Set<String> perminssionStrs = new HashSet<String>();
        if (permissionList.size()>0)
        for (Permission permission : permissionList)
        {
            perminssionStrs.add(permission.getName());
        }
        return perminssionStrs;
    }

    /**
     * 通过id 获取账号
     *
     * @param id
     * @return
     */
    @Override
    public Account getById(Integer id) {
        return baseMapper.selectById(id);
    }

    /**
     * 根据账号ID获取
     *
     * @param id
     * @return
     */
    @Override
    public AccountDTO getDTObyId(Integer id) throws InvocationTargetException, IllegalAccessException {
        return toDto(getById(id));
    }

    /**
     * 通过用户名找用户
     *
     * @param userName
     * @return
     */
    @Override
    public Account getByUserName(String userName) {
        QueryWrapper<Account> queryWrapper = new QueryWrapper<Account>();
        queryWrapper.eq("user_name",userName);
        Account account =getOne(queryWrapper);
        return account;
    }

    @Override
    public BaseResponse<Boolean> batchDel(String ids) {

        if (removeByIds(StringUtils.strtOList(ids)))
        {
            return  new BaseResponse<Boolean>(CodeEnum.SUCCESS,"批量删除成功",true);
        }
        else
        {
            return  new BaseResponse<Boolean>(CodeEnum.FAILED,"批量删除失败",false);
        }
    }

    /**
     * 根据账号添加角色
     *
     * @param map
     * @param accountId
     * @return
     */
    @Override
    public BaseResponse<Boolean> addRoles(Map<String, Object> map, Integer accountId) {

        if (accountRoleService.accountRoleList(accountId).size()>0)
        {
            //全部删除已经有的角色列表
            accountRoleService.batchDelByAccount(accountId);
            accountRoleService.batchSaveByMap(map,accountId);
            return new BaseResponse<Boolean>(CodeEnum.SUCCESS,"成功添加角色",true);


        }
        else
        {
            accountRoleService.batchSaveByMap(map,accountId);
            return new BaseResponse<Boolean>(CodeEnum.SUCCESS,"成功添加角色",true);
        }

    }


}
